﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using StonePonyMVC.StonePony.Services;
using StonePonyMVC.Models;
using System.IO;
using System.Configuration;
using System.Net.Mail;
using StonePonyMVC.StonePony.Classes;
using System.Text;

namespace StonePonyMVC.Controllers
{
    public class HomeController : StonePonyBaseController
    {
        protected static IImageService _ImageService = null;
        protected static IImageService ImageService
        {
            get
            {
                if (_ImageService == null)
                    _ImageService = new ImageService();
                return _ImageService;
            }
        }

        /// <summary>
        /// Home page
        /// <see cref="http://www.dotnet247.com/247reference/msgs/34/174771.aspx"/> for working with Access compiled queries
        /// <see cref="http://stackoverflow.com/questions/4896439/action-image-mvc3-razor"/> about displaying images
        /// <see cref="http://stackoverflow.com/questions/186062/can-an-asp-net-mvc-controller-return-an-image"/> - best one
        /// <see cref="http://www.c-sharpcorner.com/UploadFile/dhananjaycoder/imaageinmvc06172009102628AM/imaageinmvc.aspx"/>
        /// </summary>
        /// <returns></returns>
        public ActionResult Index(int? categoryId, long? sessionId)
        {
            string url = this.RootUrl;
            IEnumerable<CategoryImageDescriptor> allCategories = ImageService.GetCategoryImages(url, Server, categoryId);
            CategoryImageDescriptor selectedCategory = 
                allCategories.Where(x => x.ClassName == "Selected" && x.Cat > 0).SingleOrDefault();
            ViewBag.CategoryImages = allCategories;
            var model = new IndexModel(
                ImageService.GetAllImages(url, Server, selectedCategory == null ? String.Empty : selectedCategory.CatName));
            if (sessionId.HasValue && sessionId.Value >= 0L)
            {
                model.SessionId = sessionId.Value;
                model.EnquiredItems = ImageService.GetEnquiredImages(url, Server, sessionId.Value);
                model.EnquiredItemsCount = model.EnquiredItems.Count();
            }
            return View(model);
        }

        /// <summary>
        /// Abou page
        /// </summary>
        /// <returns></returns>
        public ActionResult About()
        {
            return View();
        }

        [HttpPost]
        public JsonResult SubmitEnquiry(SubmitEnquiryRequestModel request)
        {
            SubmitEnquiryResponseModel answer;
            if (String.IsNullOrEmpty(request.FirstName) || String.IsNullOrEmpty(request.LastName) ||
                String.IsNullOrEmpty(request.Email) || String.IsNullOrEmpty(request.ItemCode))
            {
                answer = new SubmitEnquiryResponseModel();
                answer.ErrorMessage = "Session ended. Please fill first name, last name and e-mail fields in the enquiry dialog.";
                answer.EnquiredItem = null;
                answer.Success = false;
                return Json(answer);
            }

            answer = _ImageService.WriteEnquiry(request);
            string url = this.RootUrl;      // this.Request.Url.AbsoluteUri;
            int itemCode;
            if (!answer.Success)
                return Json(answer);

            if (Int32.TryParse(request.ItemCode, out itemCode))
            {
                ImageDescriptor enquiredItem = ImageService.GetImage(url, Server, itemCode);
                if (enquiredItem.ItemCode < 0)
                {
                    answer.ErrorMessage = enquiredItem.ItemTitle;
                    answer.EnquiredItem = null;
                    answer.Success = false;
                }
                else
                    answer.EnquiredItem = enquiredItem;
            }
            else
            {
                answer.ErrorMessage = String.Format("Error: {0} is not integer", request.ItemCode);
                answer.EnquiredItem = null;
                answer.Success = false;
            }
            return Json(answer);
        }

        [HttpPost]
        public JsonResult SendEnquiry(long sessionId)
        {
            var rootUrl = string.Format("{0}://{1}{2}", Request.Url.Scheme, Request.Url.Authority, Url.Content("~"));
            LetterModel model = _ImageService.GetLetterModel(sessionId, Server, rootUrl);
            model.SiteUrl = Request.UserHostName;
            model.AdminMailAddress = ConfigurationManager.AppSettings["AdminMailAddress"];
            model.EmailSender = ConfigurationManager.AppSettings["Sender"];
            model.MailSubject = ConfigurationManager.AppSettings["MailSubject"];

            SubmitEnquiryResponseModel answer;
            try
            {
                SendMail(model);
                answer = _ImageService.SendEnquiry(sessionId);
            }
            catch (Exception ex)
            {
                answer = new SubmitEnquiryResponseModel()
                {
                    Success = false,
                    ErrorMessage = ex.Message
                };
            }
            return Json(answer);
        }
        private void SendMail(LetterModel model)
        {
            Action<string> sendMailMessage = delegate(string body)
            {
                using (var mail = new MailMessage())
                {
                    mail.To.Add(model.Email);
                    if (!String.IsNullOrEmpty(model.AdminMailAddress))
                        mail.CC.Add(model.AdminMailAddress);
                    mail.From = new MailAddress(model.EmailSender);
                    mail.Subject = model.MailSubject;
                    mail.IsBodyHtml = true;
                    mail.Body = body;

                    var smtp = new SmtpClient
                    {
                        DeliveryMethod = SmtpDeliveryMethod.Network,
                    };
                    smtp.Send(mail);
                }
            };
            var writer = new LetterWriter(model);
            string letterBody = writer.GenerateLetter();
            try
            {
                sendMailMessage(letterBody);
            }
            catch (Exception ex)
            {
                var sb = new StringBuilder();
                sb.AppendLine(DateTime.Now.ToShortTimeString());
                sb.AppendLine("Mailing error");
                sb.AppendLine(ex.Message);
                string path = Server.MapPath("/App_Data/logError.txt");
                if (!System.IO.File.Exists(path))
                    System.IO.File.Create(path);
                using (StreamWriter oFile = System.IO.File.AppendText(path))
                {
                    oFile.WriteLine(sb.ToString());
                }
                throw;
            }
        }

        [HttpPost]
        public JsonResult ClearEnquiry(long sessionId)
        {
            SubmitEnquiryResponseModel answer = _ImageService.ClearEnquiry(sessionId);
            return Json(answer);
        }

        [HttpPost]
        public JsonResult DeleteEnquiry(long sessionId, int itemcode)
        {
            SubmitEnquiryResponseModel answer = _ImageService.DeleteEnquiry(sessionId, itemcode);
            return Json(answer);
        }

        /// <summary>
        /// Returns image
        /// </summary>
        /// <param name="path"></param>
        /// <param name="id"></param>
        /// <param name="pathModifier">Word delete if image needs modification</param>
        /// <returns></returns>
        public FileResult GetImage(string path, string directory, string id, string pathModifier)
        {
            string basePath = System.Configuration.ConfigurationManager.AppSettings["ImageRootDirectory"];
            Func<string, string> getContentType = delegate(string filename)
            {
                var file = new FileInfo(filename);
                switch (file.Extension.ToUpper())
                {
                    //images
                    case ".PNG": return "image/png";
                    case ".JPG": return "image/jpeg";
                    case ".JPEG": return "image/jpeg";
                    case ".GIF": return "image/gif";
                    case ".BMP": return "image/bmp";
                    case ".TIFF": return "image/tiff";
                    default:
                        throw new NotSupportedException("The Specified File Type Is Not Supported");
                }
            };

            string virtualPath;
            if (String.IsNullOrEmpty(directory))
                virtualPath = Path.Combine(basePath, path, id);
            else
                virtualPath = Path.Combine(basePath, path, directory, id);

            string physicalPath = Server.MapPath(virtualPath);
            if (String.IsNullOrEmpty(pathModifier))
                return base.File(physicalPath, getContentType(physicalPath));
            else
                return base.File(ImageService.GetModifiedImage(physicalPath), getContentType(physicalPath));
        }
    }
}
